package com.anxin.act.task.complete.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.anxin.act.process.service.ProcessEndService;
import com.anxin.act.task.complete.TaskComplete;
import com.anxin.act.task.dao.ViewHiTaskDao;
import com.anxin.act.task.dao.WfActHiTaskDao;
import com.anxin.act.task.entity.ViewHiTask;
import com.anxin.act.task.entity.WfActHiTask;
import com.anxin.act.task.entity.WfActRuTask;
import com.anxin.act.task.service.AddTaskService;
import com.anxin.act.task.service.WfActHiCommentService;
import com.anxin.act.task.service.WfActHiTaskService;
import com.anxin.act.task.service.WfActRuTaskService;
import com.anxin.act.task.vo.FormPropertyVo;
import com.anxin.act.task.vo.TaskVo;
import com.anxin.act.utils.ActProcessUtils;
import com.anxin.act.utils.ActTaskUtils;
import com.anxin.act.utils.ActUtils;
import com.anxin.common.utils.StringUtils;
import com.anxin.common.utils.sys.UserUtils;
import com.anxin.sys.system.entity.SysUser;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;

/**
 * 自由流提交
 * @author: liuxiangyu
 * @date: 2020/4/26 16:22
 */
@Service
public class FreeFlowCompleteImpl extends TaskComplete {

    @Autowired
    private AddTaskService addTaskService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private WfActHiCommentService wfActHiCommentService;

    @Autowired
    private WfActRuTaskService wfActRuTaskService;

    @Autowired
    private WfActHiTaskService wfActHiTaskService;

    @Autowired
    private WfActHiTaskDao wfActHiTaskDao;

    @Autowired
    private ViewHiTaskDao viewHiTaskDao;

    /**
     * 提交流程
     * @param taskVo
     */
    public String complete(TaskVo taskVo){

        // 判断任务类型
        if ("actTask".equals(taskVo.getViewRuTask().getType())){
            return this.completeActTask(taskVo);
        }else {
            return this.completeAddTask(taskVo);
        }

    }

    /**
     * 提交activity任务
     * @param taskVo
     * @return
     */
    public String completeAddTask(TaskVo taskVo){
        String taskId = taskVo.getId();

        // 任务类型 申请人选择任务:freeFlow  加签任务:addBefore
        String taskType = taskVo.getViewRuTask().getType();


        // 获取下一审批人
        String nextApproval = this.getNextApproval(taskVo);
        // 审批结果
        String fieldValue = ActUtils.getFieldValue(taskVo.getFormFieldList(), "审批结果");

        // 申请人提交
        if (StringUtils.isBlank(fieldValue)){
            wfActRuTaskService.complete(taskVo.getId(),taskVo.getOpinions());
        }else if (fieldValue.equals("同意")) { // 同意
//            WfActHiTask wf = wfActHiTaskDao.getById(taskId);
//            List<WfActRuTask> wfActRuTaskList = wfActRuTaskService.findByActSourceId(wf.getSourceId());

            // 如果是 freeFlow 类型任务发起的转签，则任务任务类型也是 freeFlow
            if ("entrust".equals(taskType)) {
                WfActHiTask wfActHiTask = wfActHiTaskDao.getById(StringUtils.symbolHandler(taskId));
                if(wfActHiTask != null){
                    ViewHiTask sourceViewHiTask = viewHiTaskDao.getById(wfActHiTask.getSourceId());
                    if ("actTask".equals(sourceViewHiTask.getType()) || "freeFlow".equals(sourceViewHiTask.getType())){
                        taskType = "freeFlow";
                    }
                }
            }


            // 审批人审批并选择了下一审批人
            if (StringUtils.isNotBlank(nextApproval) && "freeFlow".endsWith(taskType)) {
                // 后加签一个节点
                SysUser user = UserUtils.getUserByUserName(nextApproval);
                JSONArray addUser = new JSONArray();
                addUser.add(user.getId());
                taskVo.setAddUser(addUser);

                // 进行后加签
                WfActHiTask wfActHiTask = wfActHiCommentService.getHiTask(taskVo);
                wfActHiTaskService.save(wfActHiTask);
                taskId = wfActHiTask.getId();

                wfActHiCommentService.addComment(taskVo,wfActHiTask.getId());

                wfActRuTaskService.addTask(taskVo);
                // 挂起流程
                addTaskService.hangTask(taskVo.getViewRuTask());
                this.updateFreeFlowApproval(taskVo.getActId());
                // 审批人审批，但没选择下一审批人
            }else {

                wfActHiCommentService.addComment(taskVo,taskVo.getId());
                //提交流程
                wfActRuTaskService.complete(taskVo.getId(),taskVo.getOpinions());

                WfActHiTask wf = wfActHiTaskDao.getById(taskId);
                List<WfActRuTask> wfActRuTaskList = wfActRuTaskService.findByActTaskId(wf.getActTaskId());

                if ("freeFlow".equals(taskType) || wfActRuTaskList.size() == 0){
                    this.updateFreeFlowApproval(taskVo.getActId());
                }

            }

        }else if (fieldValue.equals("不同意")) { // 不同意
            this.resetFreeFlowApproval(taskVo.getActId());
            wfActHiCommentService.addComment(taskVo,taskVo.getId());
            //提交流程
            wfActRuTaskService.complete(taskVo.getId(),taskVo.getOpinions());
            // 签收任务
            ActTaskUtils.claimTask(taskVo.getActId());

        }




        return taskId;
    }

    /**
     * 提交activity任务
     * @param taskVo
     * @return
     */
    public String completeActTask(TaskVo taskVo){

        String taskId = taskVo.getId();

        //保存审批意见
        super.addComment(taskVo);

        // 获取下一审批人
        String nextApproval = this.getNextApproval(taskVo);
        // String nextApproval = StringUtils.isNotBlank(taskVo.getNextApproval()) ?  UserUtils.getUser(taskVo.getNextApproval()).getUserName() : null;


        String fieldValue = ActUtils.getFieldValue(taskVo.getFormFieldList(), "审批结果");

        // 申请人提交
        if (StringUtils.isBlank(fieldValue)){
            super.taskService.complete(taskVo.getTaskId(), taskVo.getOpinions());
            List<Task> currentTaskList = ActTaskUtils.getCurrentTaskList(taskVo.getActId());
            if (currentTaskList.size() > 0 ){
                taskService.setAssignee(currentTaskList.get(0).getId(), nextApproval);
            }
            this.updateFreeFlowApproval(taskVo.getActId());
        }else if (fieldValue.equals("同意")) {
            // 审批人审批并选择了下一审批人
            if (StringUtils.isNotBlank(nextApproval)) {
                // 后加签一个节点
                SysUser user = UserUtils.getUserByUserName(nextApproval);
                JSONArray addUser = new JSONArray();
                addUser.add(user.getId());
                taskVo.setAddUser(addUser);

                // 进行后加签
                WfActHiTask wfActHiTask = wfActHiCommentService.getHiTask(taskVo);
                wfActHiTaskService.save(wfActHiTask);
                taskId = wfActHiTask.getId();

                wfActHiCommentService.addComment(taskVo,wfActHiTask.getId());

                wfActRuTaskService.addTask(taskVo);
                // 挂起流程
                addTaskService.hangTask(taskVo.getViewRuTask());
                this.updateFreeFlowApproval(taskVo.getActId());
                // 审批人审批，但没选择下一审批人
            }else if(StringUtils.isBlank(nextApproval)){
                this.updateFreeFlowApproval(taskVo.getActId());
                //提交流程
                super.taskService.complete(taskVo.getTaskId(), taskVo.getOpinions());
            }


        } else if(fieldValue.equals("不同意")) {
            //提交流程
            super.taskService.complete(taskVo.getTaskId(), taskVo.getOpinions());
            this.resetFreeFlowApproval(taskVo.getActId());
        }
        super.actTaskService.claimTaskByProcInsId(taskVo.getActId());
        //判断流程是否结束,如果结束了则执行结束后需调用的方法
        // processEndService.whetherToEnd(taskVo);

        return taskId;
    }


    /**
     * 获取下一审批人
     * @param taskVo
     * @return
     */
    public String getNextApproval(TaskVo taskVo){
        // 从流程变量中获取
        Object freeFlowAssignees = runtimeService.getVariable(taskVo.getActId(), "freeFlowAssignees");
        if (freeFlowAssignees != null){
            JSONArray freeFlowAssigneesArray = JSONObject.parseArray(freeFlowAssignees.toString());
            if (freeFlowAssigneesArray.size() > 0){
                return freeFlowAssigneesArray.getString(0);
            }
        }
        if (StringUtils.isNotBlank(taskVo.getNextApproval())){
            return UserUtils.getUser(taskVo.getNextApproval()).getUserName();
        }
        return "";
    }

    /**
     *  设置自由流审批人
     */
    public void addFreeFlowApproval(String procInsId,String assignees){
        Object freeFlowAssignees = runtimeService.getVariable(procInsId, "freeFlowAssignees");

        JSONArray freeFlowAssigneesArray;
        if (freeFlowAssignees != null){
            freeFlowAssigneesArray = JSONObject.parseArray(freeFlowAssignees.toString());
            freeFlowAssigneesArray.add(0,assignees);
        }else {
            freeFlowAssigneesArray = new JSONArray();
            freeFlowAssigneesArray.add(assignees);
        }

        runtimeService.setVariable(procInsId,"freeFlowAssignees",freeFlowAssigneesArray.toJSONString());
    }


    /**
     * 重置自由流审批人
     * @param procInsId 流程实例ID
     */
    public void resetFreeFlowApproval(String procInsId){
        Object freeFlowAssignees = runtimeService.getVariable(procInsId, "freeFlowAssigneesAll");
        runtimeService.setVariable(procInsId,"freeFlowAssignees",freeFlowAssignees);
    }

    /**
     * 设置自由流下一审批人
     * @param procInsId 流程实例ID
     */
    public void updateFreeFlowApproval(String procInsId){
        ProcessInstance processInstance = ActProcessUtils.getProcessInstance(procInsId);
        if (processInstance != null){
            Object freeFlowAssignees = runtimeService.getVariable(procInsId, "freeFlowAssignees");
            if (freeFlowAssignees != null){
                JSONArray freeFlowAssigneesArray = JSONObject.parseArray(freeFlowAssignees.toString());
                if (freeFlowAssigneesArray.size() > 0 ){
                    freeFlowAssigneesArray.remove(0);
                    runtimeService.setVariable(procInsId, "freeFlowAssignees", freeFlowAssigneesArray.toJSONString());
                }
            }
        }
    }
}
